﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace FitNesseRunner
{
	internal abstract class ExecutableTable
	{
		private readonly int _classNameColumn;
		protected readonly IReflectionProvider ReflectionProvider;

		protected ExecutableTable(IEnumerable<IEnumerable<string>> cells, int classNameColumn, IReflectionProvider reflectionProvider)
		{
			_classNameColumn = classNameColumn;
			Cells = cells;
			var rawClassName = cells.First().ElementAtOrDefault(classNameColumn);
			ClassName = rawClassName != null ? ToPascalCase(rawClassName) : null;
			ReflectionProvider = reflectionProvider;
		}

		protected virtual string ClassName { get; private set; }

		protected IEnumerable<IEnumerable<string>> Cells { get; private set; }

		public static string ToPascalCase(string rawName)
		{
			var words = rawName.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
			var pascalWords = from word in words
			                  select char.ToUpper(word[0]) + word.Substring(1);

			return string.Concat(pascalWords)/*.TrimStart('$')*/;
		}

		public abstract void ExecuteAll();

		protected object CreateInstance()
		{
			var parameters = Cells.First().Skip(1 + _classNameColumn).Select(x => x.Trim());
			return ReflectionProvider.CreateInstance(ClassName, parameters);
		}
	}
}